/*
 * controllers.h
 *
 *  Created on: Jul 6, 2009
 *      Author: jacky
 */

#ifndef CONTROLLERS_H_
#define CONTROLLERS_H_
#define NA(array) (sizeof(array)/sizeof(array[0]))
/* this Macro used for declear actions*/
#define DECLARE_ACTIONS(args...) enum { CUR_CTL(reserve),args,CUR_CTL(ACTIONEOF)}; \
extern Action CUR_CTL(actions)[CUR_CTL(ACTIONEOF)];\
extern int CUR_CTL(actionLength);

#define DEFINE_ACTIONS(arg...)  Action CUR_CTL(actions)[] = { arg };\
int CUR_CTL(actionLength)= NA(CUR_CTL(actions))

#define INIT_ACTION(actname, actionfun) [CUR_CTL(actname)]={.name = #actname,.action = actionfun}

#define DECLARE_ACTION_FUN(actionfun) static ActionStatus actionfun(HttpRequest *request,HttpResponse *response)
#define DEFINE_ACTION_FUNC(actionfun) static ActionStatus actionfun(HttpRequest *request,HttpResponse *response)
#define set(key,value) //TODO:Jacky 实现这个宏.
/**
 * ActionStatus type when action return
 */
typedef enum {
	ActionOK=0,
	ActionFAIL,
}ActionStatus;

typedef enum {
	POST,
	GET
}RequestMethod;

typedef struct HttpResponse HttpResponse;
typedef struct HttpRequest HttpRequest;
typedef struct Controller Controller;
typedef struct Action Action;
typedef ActionStatus (*ActionFUN)(HttpRequest*,HttpResponse*);
typedef void (*ViewFUN)(HttpRequest*,HttpResponse*);

struct HttpResponse {
	int autoRender; /* this is auto render flag. set 0 disable auto render*/
	int status;/* this http status. 401, 404, 500 ...*/
	char *extra_header;
	char *contentType;
	char *charset;
	FILE* Out;
	ViewFUN layout;
	ViewFUN view;
};


struct HttpRequest {
	const char* queryString;
	int ctrlid;
	int actionid;
	RequestMethod method;
	Controller *curCtrl;
	Action *curAction;
};

struct Action{
	char *name;
	ActionFUN action;
};

/**
 * Controller
 */
struct Controller {
	char *name;
	Action *actions;
	int actionLength;
};
extern Controller controllers[];
extern int controllersLength;

void HeaderContentType(HttpResponse *rsp,char *mimeType);

#endif /* CONTROLLERS_H_ */
